﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using ProgNetComponents.Collections;
using ProgNetComponents.Classes;
using DevExpress.XtraEditors.Controls;

namespace ProgNetComponents.Design.Editors.Forms
{
    public partial class ObjectArrayEditorForm : Form
    {
        object objEditValue;

        private Control oldEditor;
        private bool lockUpdate;
        private Control Editor
        {
            get
            {
                switch (this.comboType.SelectedIndex)
                {
                    case 0:
                        return null;
                    case 5:
                        return this.cmbEditor;
                    case 6:
                        return this.dtEditor;
                    case 4:
                        txtEditor.Multiline = true;
                        txtEditor.Height = 140;
                        return this.txtEditor;
                    default:
                        txtEditor.Multiline = false;
                        return this.txtEditor;
                }
            }
        }
        NamedObjectCollection coll = new NamedObjectCollection();

        private object EditValue
        {
            get
            {
                Control editor = Editor;
                if (editor != null)
                {
                    NamedObject o = comboType.SelectedItem as NamedObject;
                    if (o != null && o.Value != null)
                    {
                        if (editor == txtEditor)
                        {
                            string str = txtEditor.Text;
                            if ((Type)(o.Value) == typeof(decimal))
                                return str.AsDecimal();
                            if ((Type)(o.Value) == typeof(int))
                                return str.AsInt();
                            return str;
                        }
                        else if (editor == cmbEditor)
                        {
                            if (cmbEditor.SelectedIndex == 0)
                                return true;
                            return false;
                        }
                        else
                        {
                            return dtEditor.Value;
                        }
                    }
                }
                return null;
            }
        }
        public object[] EditValues
        {
            get
            {
                if (listBoxControl1.Items.Count == 0)
                    return null;
                List<object> l = new List<object>();
                foreach (object i in listBoxControl1.Items)
                {
                    if (i is ListBoxItem)
                        l.Add((i as ListBoxItem).Value);
                    else
                        l.Add(i);
                }
                return l.ToArray();
            }
        }
        public ObjectArrayEditorForm(object[] editValues, Type itemType = null)
        {
            InitializeComponent();
            SetTypes();
            this.comboType.DataSource = coll;
            object editValue = null;
            if (editValues != null && editValues.Length > 0)
            {
                editValue = editValues[0];
            }
            int idx = -1;
            string type = string.Empty;
            if (editValue == null)
            {
                idx = 0;
                if (itemType != null)
                    type = itemType.Name;
            }
            else
            {
                type = editValue.GetType().Name;
                if (editValues != null && editValues.Length > 0)
                {
                    foreach (object o in editValues)
                    {
                        if (o is string && o.AsString().Contains("\n"))
                        {
                            type = "String (Multiline)";
                            break;
                        }
                    }
                }
            }
            if(type.IsNotNull())
                idx = coll.IndexOf(type);

            this.comboType.SelectedIndex = idx;
            if (editValues != null && editValues.Length > 0)
            {
                listBoxControl1.Items.AddRange(editValues);
            }
            this.btnOK.Enabled = false;
        }
        private void SetTypes()
        {
            coll.Add(new NamedObject("<NULL>", null));
            AddType(typeof(int));
            AddType(typeof(decimal));
            AddType(typeof(string));
            coll.Add(new NamedObject("String (Multiline)", typeof(string)));
            AddType(typeof(bool));
            AddType(typeof(DateTime));
        }
        private void SetEditValue(object value)
        {
            Control editor = this.Editor;
            if (editor != null)
            {
                if (editor == cmbEditor)
                {
                    this.cmbEditor.SelectedIndex = this.objEditValue.AsBool() ? 0 : 1;
                }
                else if (editor.Equals((object)this.dtEditor))
                {
                    try
                    {
                        this.dtEditor.Value = this.objEditValue.AsDateTime(DateTime.Now);
                    }
                    catch
                    {
                        this.dtEditor.Value = DateTime.Now;
                    }
                }
                else
                    this.txtEditor.Text = this.objEditValue.AsString();
            }
        }
        private void AddType(Type t)
        {
            coll.Add(new NamedObject(t.Name, t));
        }

        private void comboType_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.lockUpdate = true;
            Control editor = this.Editor;
            listBoxControl1.Items.Clear();
            if (editor != null)
            {
                if (this.oldEditor != null && this.oldEditor == this.txtEditor)
                    this.objEditValue = this.oldEditor.Text;

                this.txtEditor.Visible = editor == txtEditor;
                this.cmbEditor.Visible = editor == cmbEditor;
                this.dtEditor.Visible = editor == dtEditor;

                if (editor == cmbEditor)
                {
                    this.cmbEditor.SelectedIndex = this.objEditValue.AsBool() ? 0 : 1;
                }
                else if (editor.Equals((object)this.dtEditor))
                {
                    try
                    {
                        this.dtEditor.Value = this.objEditValue.AsDateTime(DateTime.Now);
                    }
                    catch
                    {
                        this.dtEditor.Value = DateTime.Now;
                    }
                }
                else
                    this.txtEditor.Text = this.objEditValue.AsString();
                this.oldEditor = editor;
            }
            else
                this.txtEditor.Visible = this.cmbEditor.Visible = this.dtEditor.Visible = false;
            SetEditValue(null);
            this.btnOK.Enabled = true;
            this.lockUpdate = false;
        }

        private void editor_TextChanged(object sender, EventArgs e)
        {
            if (!this.lockUpdate)
                this.btnOK.Enabled = true;
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (EditValue != null)
            {
                listBoxControl1.Items.Add(EditValue);
                listBoxControl1.SelectedIndex = listBoxControl1.Items.Count - 1;
            }
            else
            {
                MessageBox.Show("Provide value to add.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            if (listBoxControl1.SelectedIndex > -1)
            {
                if (EditValue != null)
                    listBoxControl1.Items[listBoxControl1.SelectedIndex] = EditValue;
            }
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            listBoxControl1.Items.RemoveAt(listBoxControl1.SelectedIndex);
        }

        private void listBoxControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBoxControl1.SelectedIndex > -1)
            {
                objEditValue = listBoxControl1.Items[listBoxControl1.SelectedIndex];
                if (Editor != null)
                {
                    SetEditValue(objEditValue);
                }
            }
        }

    }
}
